package ca.etsmtl.logti.log619.lab05.utilities;

import java.io.IOException;
import java.util.ArrayList;

import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.internet.MimeMessage;

/**
 * Utility class to return all the content of a MimeMessage
 * @author Maxime Caumartin <maxime.caumartin.1@ens.etsmtl.ca>
 */
public class EmailSplicer {

	/**
	 * Contains the types of email parts that can be analyzed by this class.
	 * @author Maxime Caumartin <maxime.caumartin.1@ens.etsmtl.ca>
	 */
	private enum ContentTypes
	{
		Plain("text/plain"), HTML("text/html"), Multipart("multipart"), Unknown(
				"?");

		private String	type;

		ContentTypes(String type)
		{
			this.type = type;
		}

		public static ContentTypes getType(String type)
		{
			if (type.contains(Plain.type))
				return Plain;
			if (type.contains(HTML.type))
				return HTML;
			if (type.contains(Multipart.type))
				return Multipart;
			return Unknown;
		}

	}

	/**
	 * Recursive method that passes through all the parts of the Mutlipart message and returns an ArrayList<String> of the content of these parts.
	 * @param multiPartMsg The Multipart that needs to be dissected.
	 * @return The ArrayList<String> containing all the content of the Mutlipart message.
	 * @throws MessagingException Exception thrown if the analyzer cannot read the message.
	 * @throws IOException Exception thrown if the encoding type isn't valid.
	 */
	private static ArrayList<String> getMutlipartContent(Multipart multiPartMsg)
			throws MessagingException, IOException
	{
		ArrayList<String> returnTable = new ArrayList<String>(
				multiPartMsg.getCount());

		for (int i = 0; i < multiPartMsg.getCount(); i++)
		{
			switch (ContentTypes.getType(multiPartMsg.getBodyPart(i)
					.getContentType()))
			{
				case Plain:
					returnTable.add((String) multiPartMsg.getBodyPart(i)
							.getContent());
					break;
				case HTML:
					String s = org.clapper.util.html.HTMLUtil.textFromHTML((String) multiPartMsg.getBodyPart(i)
							.getContent()).trim();
					if (s.length() != 0)
						returnTable.add(s);
					break;
				case Multipart:
					returnTable
							.addAll(getMutlipartContent((Multipart) multiPartMsg
									.getBodyPart(i).getContent()));
					break;
				default:
			}
		}
		return returnTable;
	}

	/**
	 * Returns all the content of the MimeMessage passed as a parameter. The whole content will be parsed.
	 * @param message The MimeMessage containing textual information.
	 * @return The array of string containing all the strings from the content of the message.
	 * @throws MessagingException Exception thrown if the analyzer cannot read the message.
	 * @throws IOException Exception thrown if the encoding type isn't valid.
	 */
	public static String[] getMessageContent(MimeMessage message)
			throws MessagingException, IOException
	{
		String contentType = message.getContentType();

		switch (ContentTypes.getType(contentType))
		{
			case Plain:
				return new String[] { (String) message.getContent() };
			case Multipart:
				return getMutlipartContent(
						(Multipart) message.getContent()).toArray(new String[0]);
			case HTML:
				String s = org.clapper.util.html.HTMLUtil.textFromHTML((String) message
						.getContent()).trim();
				if (s.length() != 0)
					return new String[] {s};
			default:
				return new String[0];
		}

	}

}
